/**
 * Class: PeriodicTask
 *
 * Purpose: 
 *
 * Created: Jan 13, 2010 @ 10:03:50 AM
 * @author Ken Scott
 */
package org.openfantasia.util.misc;

import org.openfantasia.util.LogUtils;
import org.openfantasia.util.Utils;

public abstract class PeriodicTask implements Runnable {

	public static void main(String[] args) {
		PeriodicTask periodic = new PeriodicTask(1000L) {
			public void run() {
				LogUtils.log(System.currentTimeMillis());
			}
		};
		periodic.start();
	}

	private Thread thread;

	private boolean running = false;

	private long period = -1;

	public PeriodicTask(long periodMS) {
		if(periodMS < 100L) {
			throw new IllegalArgumentException("PeriodicTask period should not be less than 100ms (param=" + periodMS + "ms)");
		}
		this.period = periodMS;
	}

	public void start() {
		if(thread == null) {
			thread = new Thread() {
				PeriodicTask parent = PeriodicTask.this;
				public void run() {
					long delay = period;
					running = true;
					while(running) {
						Utils.waitMilliseconds(delay);
						long before = System.currentTimeMillis();
						parent.run();
						delay = period - (System.currentTimeMillis() - before);
					}
				}
			};
			thread.start();
		}
		else {
			throw new IllegalStateException();
		}
	}

	public void stop() {
		if(thread != null) {
			running = false;
		}
	}


	public abstract void run();
}
